﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using P2ClientGate;
using RiskMan.DataClass.Models.Plaza_II.FortsFootCommonRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsFutInfoRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsFutorderBookRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsFuttradeRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsInfoRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsPartRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsPosRepl;
using RiskMan.DataClass.Models.Plaza_II.FortsVmRepl;

namespace RiskMan.DataClass.Models.Plaza_II
{
    public class StockClient
    {
        #region consts
        private const String STREAM_TRADES_ID = "FORTS_FUTTRADE_REPL";
        private const String STREAM_FUTINFO_ID = "FORTS_FUTINFO_REPL";
        private const String STREAM_FortsPartRepl_ID = "FORTS_PART_REPL";


        public static bool flagOpenWindow = false;
        #endregion

        #region singleton
        protected static Object _lock = new Object();
        protected static StockClient _instance;

        public static StockClient Instance
        {
            get
            {
                lock (_lock)
                {
                    if (null == _instance)
                        _instance = new StockClient();
                    return _instance;
                }
            }
        }
        #endregion

        #region variables

        #region parameters
        private Boolean _isWorking = false;


        private CP2Connection _p2Connection;
        private CP2DataStream _p2CommonStream;
        private CP2DataStream _p2FortsFutInfoReplStream;
        private CP2DataStream _p2TradesStream;
        private CP2DataStream _p2FortsPartReplStream;


        private StreamWriter _logFile;
        #region Счетчики таблиц

        private Int64 _currentDealRevision = 0;

        #region FortsFutInfoRepl
        private Int64 _currentDeliveryReportRevision = 0;
        private Int64 _currentFutInsrtumentsRevision = 0;
        private Int64 _currentFutRejectedOrdersRevision = 0;
        private Int64 _currentFutSessContentsRevision = 0;
        private Int64 _currentFutureParamRevision = 0;
        private Int64 _currentFutVcbRevision = 0;
        private Int64 _currentMultilegDictRevision = 0;
        private Int64 _currentSessionRevision = 0;
        #endregion

        #region FortsPartRepl
        private Int64 _currentPartRevision = 0;
        #endregion
        #endregion

        #endregion

        #region properties
        public Boolean IsWorking
        {
            set { _isWorking = value; }
            get { return _isWorking; }
        }
        #endregion

        #endregion

        #region events

        #region delegates
        #region FortsFootCommonRepl
        public delegate void NewCommonArrived(Common tmp);
        #endregion
        #region FortsFutInfoRepl
        public delegate void NewDeliveryReportArrived(DeliveryReport tmp);
        public delegate void NewFutInstrumentsArrived(FutInstruments futInstruments);
        public delegate void NewFutRejectedOrdersArrived(FutRejectedOrders tmp);
        public delegate void NewFutSessContentsArrived(FutSessContents tmp);
        public delegate void NewFuturesParamsArrived(FuturesParams tmp);
        public delegate void NewFutVcbArrived(FutVcb tmp);
        public delegate void NewMultilegDictArrived(MultilegDict tmp);
        public delegate void NewSeesionArrived(Session tmp);
        #endregion
        #region FortsFutorderBookRepl
        public delegate void NewInfoArrived(Info deal);
        public delegate void NewOrdersArrived(Orders deal);
        #endregion
        #region FortsFuttradeRepl
        public delegate void NewDealArrived(Deal deal);
        public delegate void NewHeratbeatArrived(Heratbeat deal);
        public delegate void NewMultilegOrdersLogArrived(MultilegOrdersLog deal);
        public delegate void NewMultlegDealArrived(MultlegDeal deal);
        public delegate void NewOrdersLogArrived(OrdersLog deal);
        public delegate void NewSysEventsArrived(SysEvents deal);
        #endregion
        #region FortsInfoRepl
        public delegate void NewBaseContractsParamsArrived(BaseContractsParams deal);
        #endregion
        #region FortsOrdlogRepl
        public delegate void NewBaseFortsOrdlogReplMultilegOrdersLogArrived(FortsOrdlogRepl.MultilegOrdersLog deal);
        public delegate void NewBaseFortsOrdlogReplOrdersLogArrived(FortsOrdlogRepl.OrdersLog deal);
        public delegate void NewBaseFortsOrdlogReplSysEventsArrived(FortsOrdlogRepl.SysEvents deal);
        #endregion
        #region FortsPartRepl
        public delegate void NewBasePartArrived(Part deal);
        #endregion
        #region FortsPosRepl
        public delegate void NewBasePositionArrived(Position deal);
        #endregion
        #region FortsVmRepl
        public delegate void NewBaseFutVmArrived(FutVm deal);
        #endregion
        //public delegate void NewDealArrived(Deal deal);

        #endregion

        #region events

        #region FortsFootCommonRepl
        public event NewCommonArrived OnNewCommonArrived;
        #endregion
        #region FortsFutInfoRepl
        public event NewDeliveryReportArrived OnNewDeliveryReportArrived;
        public event NewFutInstrumentsArrived OnNewFutInstrumentsArrived;
        public event NewFutRejectedOrdersArrived OnNewFutRejectedOrdersArrived;
        public event NewFutSessContentsArrived OnNewFutSessContentsArrived;
        public event NewFuturesParamsArrived OnNewFuturesParamsArrived;
        public event NewFutVcbArrived OnNewFutVcbArrived;
        public event NewMultilegDictArrived OnNewMultilegDictArrived;
        public event NewSeesionArrived OnNewSeesionArrived;
        #endregion
        #region FortsFutorderBookRepl
        public event NewInfoArrived OnNewInfoArrived;
        public event NewOrdersArrived OnNewOrdersArrived;
        #endregion
        #region FortsFuttradeRepl
        public event NewDealArrived OnNewDealArrived;
        public event NewHeratbeatArrived OnNewHeratbeatArrived;
        public event NewMultilegOrdersLogArrived OnNewMultilegOrdersLogArrived;
        public event NewMultlegDealArrived OnNewMultlegDealArrived;
        public event NewOrdersLogArrived OnNewOrdersLogArrived;
        public event NewSysEventsArrived OnNewSysEventsArrived;
        #endregion
        #region FortsInfoRepl
        public event NewBaseContractsParamsArrived OnNewBaseContractsParamsArrived;
        #endregion
        #region FortsOrdlogRepl
        public event NewBaseFortsOrdlogReplMultilegOrdersLogArrived OnNewBaseFortsOrdlogReplMultilegOrdersLogArrived;
        public event NewBaseFortsOrdlogReplOrdersLogArrived OnNewBaseFortsOrdlogReplOrdersLogArrived;
        public event NewBaseFortsOrdlogReplSysEventsArrived OnNewBaseFortsOrdlogReplSysEventsArrived;
        #endregion
        #region FortsPartRepl
        public event NewBasePartArrived OnNewBasePartArrived;
        #endregion
        #region FortsPosRepl
        public event NewBasePositionArrived OnNewBasePositionArrived;
        #endregion
        #region FortsVmRepl
        public event NewBaseFutVmArrived OnNewBaseFutVmArrived;
        #endregion


        #endregion

        #region raise

        #region FortsFootCommonRepl
        private void Raise_NewCommonArrived(Common tmp)
        {
            if (null != tmp && null != OnNewCommonArrived)
                OnNewCommonArrived(tmp);
        }
        #endregion
        #region FortsFutInfoRepl
        private void Raise_NewDeliveryReportArrived(DeliveryReport tmp)
        {

            if (null != tmp && null != OnNewDeliveryReportArrived)
                OnNewDeliveryReportArrived(tmp);
        }
        private void Raise_NewFutInstrumentsArrived(FutInstruments futInstruments)
        {
            if (null != futInstruments && null != OnNewFutInstrumentsArrived)
                OnNewFutInstrumentsArrived(futInstruments);
        }
        private void Raise_NewFutRejectedOrdersArrived(FutRejectedOrders tmp)
        {
            if (null != tmp && null != OnNewFutRejectedOrdersArrived)
                OnNewFutRejectedOrdersArrived(tmp);
        }
        private void Raise_NewFutSessContentsArrived(FutSessContents tmp)
        {
            if (null != tmp && null != OnNewFutSessContentsArrived)
                OnNewFutSessContentsArrived(tmp);
        }
        private void Raise_NewFuturesParamsArrived(FuturesParams tmp)
        {
            if (null != tmp && null != OnNewFuturesParamsArrived)
                OnNewFuturesParamsArrived(tmp);
        }
        private void Raise_NewFutVcbArrived(FutVcb tmp)
        {
            if (null != tmp && null != OnNewFutVcbArrived)
                OnNewFutVcbArrived(tmp);
        }
        private void Raise_NewMultilegDictArrived(MultilegDict tmp)
        {
            if (null != tmp && null != OnNewMultilegDictArrived)
                OnNewMultilegDictArrived(tmp);
        }
        private void Raise_NewSeesionArrived(Session tmp)
        {
            if (null != tmp && null != OnNewSeesionArrived)
                OnNewSeesionArrived(tmp);
        }
        #endregion
        #region FortsFutorderBookRepl
        private void Raise_NewInfoArrived(Info deal)
        {
            if (null != deal && null != OnNewInfoArrived)
                OnNewInfoArrived(deal);
        }
        private void Raise_NewOrdersArrived(Orders deal)
        {
            if (null != deal && null != OnNewOrdersArrived)
                OnNewOrdersArrived(deal);
        }
        #endregion
        #region FortsFuttradeRepl
        private void Raise_NewDealArrived(Deal deal)
        {
            if (null != deal && null != OnNewDealArrived)
                OnNewDealArrived(deal);
        }
        private void Raise_NewHeratbeatArrived(Heratbeat deal)
        {
            if (null != deal && null != OnNewHeratbeatArrived)
                OnNewHeratbeatArrived(deal);
        }
        private void Raise_NewMultilegOrdersLogArrived(MultilegOrdersLog deal)
        {
            if (null != deal && null != OnNewMultilegOrdersLogArrived)
                OnNewMultilegOrdersLogArrived(deal);
        }
        private void Raise_NewMultlegDealArrived(MultlegDeal deal)
        {
            if (null != deal && null != OnNewMultlegDealArrived)
                OnNewMultlegDealArrived(deal);
        }
        private void Raise_NewOrdersLogArrived(OrdersLog deal)
        {
            if (null != deal && null != OnNewOrdersLogArrived)
                OnNewOrdersLogArrived(deal);
        }
        private void Raise_NewSysEventsArrived(SysEvents deal)
        {
            if (null != deal && null != OnNewSysEventsArrived)
                OnNewSysEventsArrived(deal);
        }
        #endregion
        #region FortsInfoRepl
        private void Raise_NewBaseContractsParamsArrived(BaseContractsParams deal)
        {
            if (null != deal && null != OnNewBaseContractsParamsArrived)
                OnNewBaseContractsParamsArrived(deal);
        }
        #endregion
        #region FortsOrdlogRepl
        private void Raise_NewBaseFortsOrdlogReplMultilegOrdersLogArrived(FortsOrdlogRepl.MultilegOrdersLog deal)
        {
            if (null != deal && null != OnNewBaseFortsOrdlogReplMultilegOrdersLogArrived)
                OnNewBaseFortsOrdlogReplMultilegOrdersLogArrived(deal);
        }
        private void Raise_NewBaseFortsOrdlogReplOrdersLogArrived(FortsOrdlogRepl.OrdersLog deal)
        {
            if (null != deal && null != OnNewBaseFortsOrdlogReplOrdersLogArrived)
                OnNewBaseFortsOrdlogReplOrdersLogArrived(deal);
        }
        private void Raise_NewBaseFortsOrdlogReplSysEventsArrived(FortsOrdlogRepl.SysEvents deal)
        {
            if (null != deal && null != OnNewBaseFortsOrdlogReplSysEventsArrived)
                OnNewBaseFortsOrdlogReplSysEventsArrived(deal);
        }
        #endregion
        #region FortsPartRepl
        private void Raise_NewPartArrived(Part deal)
        {
            if (null != deal && null != OnNewBasePartArrived)
                OnNewBasePartArrived(deal);
        }
        #endregion
        #region FortsPosRepl
        private void Raise_NewBasePositionArrived(Position deal)
        {
            if (null != deal && null != OnNewBasePositionArrived)
                OnNewBasePositionArrived(deal);
        }
        #endregion
        #region FortsVmRepl
        private void Raise_NewBaseFutVmArrived(FutVm deal)
        {
            if (null != deal && null != OnNewBaseFutVmArrived)
                OnNewBaseFutVmArrived(deal);
        }
        #endregion



        #endregion

        #endregion



        #region public functionality
        public void Initiate()
        {
            _p2Connection = new CP2ConnectionClass();
            _p2Connection.Host = "localhost"; // TODO: Вынести в настройки
            _p2Connection.Port = 4001; // TODO: Вынести в настройки
            _p2Connection.AppName = "p2clientgate_forts"; // TODO: Вынести в настройки

            IP2ConnectionEvent_ConnectionStatusChangedEventHandler connStatusEventHandler = new IP2ConnectionEvent_ConnectionStatusChangedEventHandler(P2Connection_OnStatusChanged);
            _p2Connection.ConnectionStatusChanged += connStatusEventHandler;

            // Сделки ?
            _p2TradesStream = new CP2DataStreamClass();
            _p2TradesStream.DBConnString = ""; // Безбазовый подход
            _p2TradesStream.type = TRequestType.RT_COMBINED_DYNAMIC;
            _p2TradesStream.StreamName = STREAM_TRADES_ID;

            _p2TradesStream.TableSet = new CP2TableSetClass();
            _p2TradesStream.TableSet.InitFromIni2("forts_scheme.ini", "FutTrade");
            _p2TradesStream.TableSet.set_rev("deal", _currentDealRevision + 1);

            //Инструменты
            #region FortsFutInfoRepl

            _p2FortsFutInfoReplStream = new CP2DataStreamClass();
            _p2FortsFutInfoReplStream.DBConnString = ""; // Безбазовый подход
            _p2FortsFutInfoReplStream.type = TRequestType.RT_COMBINED_DYNAMIC;
            _p2FortsFutInfoReplStream.StreamName = STREAM_FUTINFO_ID;

            _p2FortsFutInfoReplStream.TableSet = new CP2TableSetClass();
            _p2FortsFutInfoReplStream.TableSet.InitFromIni2("forts_scheme.ini", "FutInfo");
            _p2FortsFutInfoReplStream.TableSet.set_rev("delivery_report", _currentDeliveryReportRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("fut_instruments", _currentFutInsrtumentsRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("fut_rejected_orders", _currentFutRejectedOrdersRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("fut_sess_contents", _currentFutSessContentsRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("futures_params", _currentFutureParamRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("fut_vcb", _currentFutVcbRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("multileg_dict", _currentMultilegDictRevision + 1);
            _p2FortsFutInfoReplStream.TableSet.set_rev("session", _currentSessionRevision + 1);

            #endregion
            #region MyRegFortsPartReplion

            _p2FortsPartReplStream = new CP2DataStreamClass();
            _p2FortsPartReplStream.DBConnString = ""; // Безбазовый подход
            _p2FortsPartReplStream.type = TRequestType.RT_COMBINED_DYNAMIC;
            _p2FortsPartReplStream.StreamName = STREAM_FortsPartRepl_ID;

            _p2FortsPartReplStream.TableSet = new CP2TableSetClass();
            _p2FortsPartReplStream.TableSet.InitFromIni2("forts_scheme.ini", "FutTrade");
            _p2FortsPartReplStream.TableSet.set_rev("part", _currentPartRevision + 1);
            #endregion

            // Хэндлер состояния
            IP2DataStreamEvents_StreamStateChangedEventHandler dsStateHandler = new IP2DataStreamEvents_StreamStateChangedEventHandler(TradesStream_OnStateChanged);
            _p2TradesStream.StreamStateChanged += dsStateHandler;
            _p2FortsFutInfoReplStream.StreamStateChanged += dsStateHandler;
            _p2FortsPartReplStream.StreamStateChanged += dsStateHandler;

            // Хэндлер добавления данных
            IP2DataStreamEvents_StreamDataInsertedEventHandler dsInsertedHandler = new IP2DataStreamEvents_StreamDataInsertedEventHandler(TradesStream_OnDataInserted);
            _p2TradesStream.StreamDataInserted += dsInsertedHandler;
            _p2FortsFutInfoReplStream.StreamDataInserted += dsInsertedHandler;
            _p2FortsPartReplStream.StreamDataInserted += dsInsertedHandler;

            // Хэндлер удаления данных
            IP2DataStreamEvents_StreamDataDeletedEventHandler dsDeletedHandler = new IP2DataStreamEvents_StreamDataDeletedEventHandler(TradesStream_OnDataDeleted);
            _p2TradesStream.StreamDataDeleted += dsDeletedHandler;
            _p2FortsFutInfoReplStream.StreamDataDeleted += dsDeletedHandler;
            _p2FortsPartReplStream.StreamDataDeleted += dsDeletedHandler;
            // Хэндлер времени жизни
            IP2DataStreamEvents_StreamLifeNumChangedEventHandler dsLifeNumHandler = new IP2DataStreamEvents_StreamLifeNumChangedEventHandler(TradesStream_OnLifeNumChanged);
            _p2TradesStream.StreamLifeNumChanged += dsLifeNumHandler;
            _p2FortsFutInfoReplStream.StreamLifeNumChanged += dsLifeNumHandler;
            _p2FortsPartReplStream.StreamLifeNumChanged += dsLifeNumHandler;
            _isWorking = true;
        }

        public void Run()
        {


            while (_isWorking)
            {
                //if (flagOpenWindow)
                try
                {
                    _p2Connection.Connect();
                    try
                    {
                        while (_isWorking)
                        {
                            OpenStream(_p2TradesStream, "deal", _currentDealRevision + 1);

                            uint cookie;
                            _p2Connection.ProcessMessage(out cookie, 100);

                            #region FortsFutInfoRepl
                            OpenStream(_p2FortsFutInfoReplStream, "delivery_report", _currentDeliveryReportRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "fut_instruments", _currentFutInsrtumentsRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "fut_rejected_orders", _currentFutRejectedOrdersRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "fut_sess_contents", _currentFutSessContentsRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "futures_params", _currentFutureParamRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "fut_vcb", _currentFutVcbRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "multileg_dict", _currentMultilegDictRevision + 1);
                            OpenStream(_p2FortsFutInfoReplStream, "session", _currentSessionRevision + 1);
                            #endregion

                            uint cookie2;

                            #region FortsPartRepl
                            _p2Connection.ProcessMessage(out cookie2, 100);
                            OpenStream(_p2FortsPartReplStream, "part", _currentPartRevision + 1);
                            #endregion

                            uint cookie3;
                            _p2Connection.ProcessMessage(out cookie3, 100);
                        }
                    }
                    catch (COMException exc2)
                    {
                        LogWriteLine("Исключение {0} {1:X}", exc2.Message, exc2.ErrorCode);
                    }

                    if (_p2TradesStream.State != TDataStreamState.DS_STATE_CLOSE)
                    {
                        try
                        {
                            _p2TradesStream.Close();
                        }
                        catch (COMException exc2)
                        {
                            LogWriteLine("Исключение {0} {1:X}", exc2.Message, exc2.ErrorCode);
                        }
                    }

                    _p2Connection.Disconnect();
                }
                catch (COMException exc3)
                {
                    LogWriteLine("Исключение {0} {1:X}", exc3.Message, exc3.ErrorCode);
                }
                catch (Exception exc4)
                {
                    LogWriteLine("Исключение {0} {1}", exc4.Message, exc4.Source);
                }
            }
        }
        #endregion

        #region supplementary
        private void LogWriteLine(String fmt, params object[] args)
        {
            if (null == _logFile)
                _logFile = new StreamWriter("GetOrders.general.log", true, System.Text.Encoding.UTF8);

            _logFile.WriteLine(fmt, args);
            _logFile.Flush();
        }

        private void OpenStream(CP2DataStream stream, String tableName, long revision)
        {
            try
            {
                if (stream.State == TDataStreamState.DS_STATE_ERROR ||
                    stream.State == TDataStreamState.DS_STATE_CLOSE)
                {
                    if (stream.State == TDataStreamState.DS_STATE_ERROR)
                        stream.Close();

                    stream.TableSet.set_rev(tableName, revision + 1);
                    stream.Open(_p2Connection);
                }
            }
            catch (COMException exc)
            {
                LogWriteLine("Исключение {0} {1:X}", exc.Message, exc.ErrorCode);
            }
        }
        #endregion

        #region event handlers
        private void P2Connection_OnStatusChanged(CP2Connection connection, TConnectionStatus status)
        {
            StringBuilder state = new StringBuilder();
            state.Append("Соединение с MQ: ");

            if ((status & TConnectionStatus.CS_CONNECTION_BUSY) == TConnectionStatus.CS_CONNECTION_BUSY)
                state.Append("ЗАНЯТ");
            else if ((status & TConnectionStatus.CS_CONNECTION_CONNECTED) == TConnectionStatus.CS_CONNECTION_CONNECTED)
            {
                state.Append("ПОДКЛЮЧЕНО");
                MainWindow.StaticLevel.Connecting(true);
            }
            else if ((status & TConnectionStatus.CS_CONNECTION_DISCONNECTED) ==
                     TConnectionStatus.CS_CONNECTION_DISCONNECTED)
            {
                MainWindow.StaticLevel.Connecting(false);
                state.Append("ОТКЛЮЧЕНО");
            }
            else if ((status & TConnectionStatus.CS_CONNECTION_INVALID) == TConnectionStatus.CS_CONNECTION_INVALID)
                state.Append("НЕПРАВИЛЬНО");

            state.Append(" состояние роутера: ");

            if ((status & TConnectionStatus.CS_ROUTER_CONNECTED) == TConnectionStatus.CS_ROUTER_CONNECTED)
                state.Append("ПОДКЛЮЧЕН");
            else if ((status & TConnectionStatus.CS_ROUTER_DISCONNECTED) == TConnectionStatus.CS_ROUTER_DISCONNECTED)
                state.Append("ОТКЛЮЧЕН");
            else if ((status & TConnectionStatus.CS_ROUTER_LOGINFAILED) == TConnectionStatus.CS_ROUTER_LOGINFAILED)
                state.Append("ЛОГИН НЕВЕРЕН");
            else if ((status & TConnectionStatus.CS_ROUTER_NOCONNECT) == TConnectionStatus.CS_ROUTER_NOCONNECT)
                state.Append("НЕТ СОЕДИНЕНИЯ");
            else if ((status & TConnectionStatus.CS_ROUTER_RECONNECTING) == TConnectionStatus.CS_ROUTER_RECONNECTING)
                state.Append("ПЕРЕПОДКЛЮЧАЕТСЯ...");


            LogWriteLine(state.ToString());
        }

        private void TradesStream_OnStateChanged(CP2DataStream stream, TDataStreamState state)
        {
            StringBuilder bld = new StringBuilder();

            bld.AppendFormat("Поток данных {0} изменил состояние на ", stream.StreamName);

            switch (state)
            {
                case TDataStreamState.DS_STATE_CLOSE: bld.Append("ЗАКРЫТ"); break;
                case TDataStreamState.DS_STATE_CLOSE_COMPLETE: bld.Append("ЗАКРЫТ.ЗАВЕРШЕН"); break;
                case TDataStreamState.DS_STATE_ERROR: bld.Append("ОШИБКА"); break;
                case TDataStreamState.DS_STATE_LOCAL_SNAPSHOT: bld.Append("ЛОКАЛЬНЫЙ СНИМОК"); break;
                case TDataStreamState.DS_STATE_ONLINE: bld.Append("АКТИВЕН"); break;
                case TDataStreamState.DS_STATE_REMOTE_SNAPSHOT: bld.Append("СНИМОК С СЕРВЕРА"); break;
                case TDataStreamState.DS_STATE_REOPEN: bld.Append("ПЕРЕОТКРЫТ"); break;
            };

            LogWriteLine(bld.ToString());
        }

        private void TradesStream_OnDataInserted(CP2DataStream stream, String tableName, CP2Record record)
        {
            try
            {
                String start = String.Format("Новая запись в таблицу {0}: ", tableName);

                if (stream.StreamName == STREAM_TRADES_ID && tableName == "deal")
                {
                    var relation = ParseFieldFromStream(_p2TradesStream, record, start, "deal", out _currentDealRevision);

                    Deal deal = Deal.ParseDeal(relation);
                    Deal.AddValueToObsColDeal(deal);
                    Raise_NewDealArrived(deal);
                }

                #region FortsFutInfoRepl

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "delivery_report")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "delivery_report", out  _currentDeliveryReportRevision);

                    DeliveryReport tmp = DeliveryReport.ParseDeliveryReport(relation);
                    DeliveryReport.AddValueToObsColFutRejectedOrders(tmp);
                    Raise_NewDeliveryReportArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "fut_instruments")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "fut_instruments", out  _currentFutInsrtumentsRevision);

                    FutInstruments futInstruments = FutInstruments.ParseFutInstruments(relation);
                    FutInstruments.AddValueToObsColFutInstruments(futInstruments);
                    Raise_NewFutInstrumentsArrived(futInstruments);
                }
                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "fut_rejected_orders")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "fut_rejected_orders", out _currentFutRejectedOrdersRevision);

                    FutRejectedOrders tmp = FutRejectedOrders.ParseFutInstruments(relation);
                    FutRejectedOrders.AddValueToObsColFutRejectedOrders(tmp);
                    Raise_NewFutRejectedOrdersArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "fut_sess_contents")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "fut_sess_contents", out _currentFutSessContentsRevision);

                    FutSessContents tmp = FutSessContents.ParseFutSessContents(relation);
                    FutSessContents.AddValueToObsColFutSessContents(tmp);
                    Raise_NewFutSessContentsArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "futures_params")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "futures_params", out _currentFutureParamRevision);

                    FuturesParams tmp = FuturesParams.ParseFuturesParams(relation);
                    FuturesParams.AddValueToObsColFuturesParams(tmp);
                    Raise_NewFuturesParamsArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "fut_vcb")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "fut_vcb", out _currentFutVcbRevision);

                    FutVcb tmp = FutVcb.ParseFutVcb(relation);
                    FutVcb.AddValueToObsColFutVcb(tmp);
                    Raise_NewFutVcbArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "multileg_dict")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "multileg_dict", out _currentMultilegDictRevision);

                    MultilegDict tmp = MultilegDict.ParseMultilegDict(relation);
                    MultilegDict.AddValueToObsColMultilegDict(tmp);
                    Raise_NewMultilegDictArrived(tmp);
                }

                if (stream.StreamName == STREAM_FUTINFO_ID && tableName == "session")
                {
                    var relation = ParseFieldFromStream(_p2FortsFutInfoReplStream, record, start, "session", out _currentSessionRevision);

                    Session tmp = Session.ParseSeesion(relation);
                    Session.AddValueToObsColSession(tmp);
                    Raise_NewSeesionArrived(tmp);
                }
                #endregion

                #region FortsPartRepl
                if (stream.StreamName == STREAM_TRADES_ID && tableName == "part")
                {
                    var relation = ParseFieldFromStream(_p2FortsPartReplStream, record, start, "part", out _currentPartRevision);

                    Part tmp = Part.ParsePart(relation);
                    Part.AddValueToObsColPart(tmp);
                    Raise_NewPartArrived(tmp);
                }
                #endregion
            }
            catch (Exception exc)
            {
                LogWriteLine(String.Format("Исключение {0} источник {1}", exc.Message, exc.Source));
            }
        }

        private Dictionary<string, string> ParseFieldFromStream(CP2DataStream stream, CP2Record record, string start, string tableName, out Int64 currtneRev)
        {
            String fields = stream.TableSet.get_FieldList(tableName);

            StringBuilder bld = new StringBuilder();
            bld.Append(start);

            Dictionary<String, String> relation = new Dictionary<String, String>();

            currtneRev = record.GetValAsLongByIndex(1);

            String[] parts = fields.Split(',');
            for (uint i = 0; i < parts.Length; ++i)
            {
                String field = parts[i];
                String value = "";
                try
                {
                    value = record.GetValAsString(field);
                    bld.AppendFormat("{0} -> {1}; ", field, value);

                    relation[field] = value;
                }
                catch (Exception e)
                {
                    // do nothing
                }
            }

            LogWriteLine(bld.ToString());
            return relation;
        }

        private void TradesStream_OnDataDeleted(CP2DataStream stream, String tableName, Int64 id, CP2Record record)
        {
            LogWriteLine(String.Format("Удалена запись из таблицы {0} с идентификатором {1}", tableName, id));
        }

        private void TradesStream_OnLifeNumChanged(CP2DataStream stream, int lifeNum)
        {
            if (stream.StreamName == STREAM_TRADES_ID)
            {
                _p2TradesStream.TableSet.LifeNum = lifeNum;
                _p2TradesStream.TableSet.SetLifeNumToIni("forts_scheme.ini");

                LogWriteLine(String.Format("Для потока {0} пришло новое значение LifeNum {1}", stream.StreamName, lifeNum));
            }
        }
        #endregion
    }
}
